/***************************************************************************
 *   Copyright (C) 2007 by Warren Kenny   *
 *   warren.kenny@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <otaServerResponse.h>
#include <otaMySQLCommonHeader.h>

otaServerResponse::otaServerResponse()
: m_fields( 0 ),
  m_rows( 0 ),
  m_autoIncrement( 0 )
{
}

bool otaServerResponse::deserialize( const char *data, unsigned int dataSize, const unsigned int offset, unsigned int &newOffset )
{
	otaMySQLCommonHeader header;
	unsigned int temp = offset;
	bool ok = false;
	if( header.deserialize( data, dataSize, offset, temp ) )
	{
		std::cout << "received server response" << std::endl;
		ok = otaBytePacker::removeBasicType( data, dataSize, offset, temp, m_type );
		switch(m_type)
		{
			case OTA_SERVER_RESPONSE_OK:
				ok = ok && processOK( data, dataSize, temp, newOffset );
			break;	
			
			case OTA_SERVER_RESPONSE_ERROR:
				ok = ok && processError( data, dataSize, temp, newOffset );
			break;
			
			case OTA_SERVER_RESPONSE_END_OF_FIELD:
				ok = true;
			break;
			
			default:
				m_type = OTA_SERVER_RESPONSE_RESULT_DATA;
				ok = ok && processResults( data, dataSize, offset, newOffset );
		}
	}
	return ok;
}

unsigned int otaServerResponse::getType()
{
	return m_type;
}
void otaServerResponse::getResponseData(	unsigned int &type, 
     						unsigned int &packetCount, 
	   					unsigned int &byteCount, 
	 					unsigned long &autoIncrement,
        					unsigned long &rows, 
	     					unsigned long &fields, 
	   					unsigned long &errNo, 
	 					std::string &message)
{
	type = m_type;
	packetCount = m_packetCount;
	byteCount = m_byteCount;
	autoIncrement = m_autoIncrement;
	rows = m_rows;
	fields = m_fields;
	message = m_message;
}

bool otaServerResponse::processOK( const char *data, unsigned int dataSize, const unsigned int offset, unsigned int &newOffset )
{
	m_packetCount = 1;
	return (	otaBytePacker::removeLEBinary( data, dataSize, offset, newOffset, m_rows ) &&
			otaBytePacker::removeLEBinary( data, dataSize, newOffset, newOffset, m_autoIncrement ) &&
			otaBytePacker::removeNTString( data, dataSize, newOffset, newOffset, m_message ) );
}
	
bool otaServerResponse::processError( const char *data, unsigned int dataSize, const unsigned int offset, unsigned int &newOffset )
{
	m_packetCount = 1;
	return (	otaBytePacker::removeLEBinary( data, dataSize, offset, newOffset, m_errNo ) &&
			otaBytePacker::removeNTString( data, dataSize, newOffset, newOffset, m_message ) );
}
	
bool otaServerResponse::processResults( const char *data, unsigned int dataSize, const unsigned int offset, unsigned int &newOffset )
{
	otaMySQLCommonHeader header;
	bool ok = header.deserialize( data, dataSize, offset, newOffset );
	if( ok )
	{
		m_packetCount = 1;
		if( header.getSequenceNumber() == 1 )
		{
			ok = ok && otaBytePacker::removeLEBinary( data, dataSize, newOffset, newOffset, m_fields );
			newOffset += header.getBodyLength();
			for( unsigned int j = 0; j < m_fields; j++ )
			{
				header.deserialize( data, dataSize, newOffset, newOffset );
				newOffset += header.getBodyLength();
				m_packetCount++;
			}
		}
		
		unsigned char packetType;
		
		while( ok )
		{
			ok = ( 	header.deserialize( data, dataSize, newOffset, newOffset ) &&
				otaBytePacker::removeBasicType( data, dataSize, newOffset, newOffset, packetType ) );
			if( ok )
			{
				if(packetType != 0xFE)
				{
					m_rows++;
				}
				newOffset += header.getBodyLength();
				m_packetCount++;
			}
		}
		return true;
	}
	return false;
}

otaServerResponse::~otaServerResponse()
{
}


